<html>
<head><meta charset="utf-8"><title>Copy Elision And related optimizations · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html">Copy Elision And related optimizations</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="216007923"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216007923" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216007923">(Nov 08 2020 at 13:45)</a>:</h4>
<p>C++ permits the implementation to remove calls to copy and move constructors in certain situtations (and even requires some, as of C++17). <br>
This is important because copy and move construction can be non-trivial, however in rust, all moves and copies are trivial.<br>
However, certain optimizations may cause other issues, for example, Return Value Optimization, and likewise Named Return Value Optimization. These respectively permits (requires in C++17) that rvalue returns be constructed directly into the object initialized by the return value, and permits the same when the return value is the name of a local variable that isn't a parameter.  This can alter the number and type of parameters, as it requires passing an invisible parameter of type <code>*mut R</code> for all functions of type <code>unsafe? extern"ABI"? fn(Args...)-&gt;R</code> (where <code>Args...</code> is the list of parameters). </p>
<p>The main questions are if RVO and NRVO would in fact be permitted by Rust, and whether or not there are any  limitations I am unaware of that would block such.</p>



<a name="216008167"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216008167" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216008167">(Nov 08 2020 at 13:53)</a>:</h4>
<p>RVO (or is it NRVO?) can already be performed when mir optimizations are enabled. A return parameter is already used as part of both the Rust and (in case of the SystemV abi) the C abi when the return value doesn't fit in registers.</p>



<a name="216008175"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216008175" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Diggsey <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216008175">(Nov 08 2020 at 13:53)</a>:</h4>
<p>One thing that should make RVO easier in Rust is that all types can be trivially moved. (Compared to C++ where a type may rely on its own address)</p>



<a name="216009544"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216009544" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pachi <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216009544">(Nov 08 2020 at 14:32)</a>:</h4>
<p>IIRC the problem in Rust is more about whether those optimizations can be always guaranteeded or not for some users (so, for instance, you can ensure that a value can be built in the destination without intermediate allocation).</p>



<a name="216014241"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216014241" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216014241">(Nov 08 2020 at 16:38)</a>:</h4>
<p>The Rust call ABI is not defined, so we can add such invisible parameters as we see fit</p>



<a name="216021807"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216021807" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216021807">(Nov 08 2020 at 19:39)</a>:</h4>
<p>I'd say that that C++ being able to remove copy constructors is more like Rust getting the ability to remove <code>Clone::clone</code> calls.  (Which seems plausible to me -- turning it into a move if it's known to be the last use after some MIR optimizations or what have you.)</p>



<a name="216022081"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216022081" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216022081">(Nov 08 2020 at 19:46)</a>:</h4>
<p><span class="user-mention silent" data-user-id="125270">scottmcm</span> <a href="#narrow/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations/near/216021807">said</a>:</p>
<blockquote>
<p>I'd say that that C++ being able to remove copy constructors is more like Rust getting the ability to remove <code>Clone::clone</code> calls.  (Which seems plausible to me -- turning it into a move if it's known to be the last use after some MIR optimizations or what have you.)</p>
</blockquote>
<p>I think that's impossible in general without some unsafe marker traits, the <code>clone</code> could have observable side-effects</p>



<a name="216022141"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216022141" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216022141">(Nov 08 2020 at 19:47)</a>:</h4>
<p>I'm not a big fan of adding some weasly language to the spec which says that those calls may be omitted under some conditions... letting the compiler remove effectful function calls is really dubious (in particular in a safe language), and the need is much less pressing than in C++ since Rust does not have nearly as much <code>clone</code> as C++ has implicit copy constructor calls</p>



<a name="216022205"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216022205" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216022205">(Nov 08 2020 at 19:48)</a>:</h4>
<p>note that the conditions under which <code>clone</code> can be removed would have to be spelled out entirely in terms of the surface language (like C++ does), not in terms of however the MIR looks after a bunch of optimizations -- it needs to be crystal clear to the programmer when we are allowed to remove function calls that they explicitly wrote down should happen</p>



<a name="216022281"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216022281" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216022281">(Nov 08 2020 at 19:50)</a>:</h4>
<p>Ah, interesting.  Being syntactic definitely makes this less useful, since that makes it a place where the existing "you don't need <code>.clone()</code> here" lints work.</p>



<a name="216022298"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216022298" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216022298">(Nov 08 2020 at 19:50)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations/near/216022205">said</a>:</p>
<blockquote>
<p>note that the conditions under which <code>clone</code> can be removed would have to be spelled out entirely in terms of the surface language (like C++ does), not in terms of however the MIR looks after a bunch of optimizations -- it needs to be crystal clear to the programmer when we are allowed to remove function calls that they explicitly wrote down should happen</p>
</blockquote>
<p>Aren't the current plans for rust specification directed at the MIR? Or do you mean that this is an additional design constraint on the spec</p>



<a name="216024078"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024078" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024078">(Nov 08 2020 at 20:34)</a>:</h4>
<blockquote>
<p>Aren't the current plans for rust specification directed at the MIR? Or do you mean that this is an additional design constraint on the spec</p>
</blockquote>
<p>my plan was to do the spec in terms of some "miniRust" MIR-like language -- for languages with large surface syntax, it is usually best to first translate them to a "core language" and then give precise semantics to the core language</p>



<a name="216024082"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024082" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024082">(Nov 08 2020 at 20:34)</a>:</h4>
<p>but of course the translation from surface Rust to "miniRust" also needs to be made precise, that is part of the spec then</p>



<a name="216024094"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024094" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024094">(Nov 08 2020 at 20:35)</a>:</h4>
<p>Right. And MIR isn't eligible as "miniRust" because it is still too big?</p>



<a name="216024096"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024096" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024096">(Nov 08 2020 at 20:35)</a>:</h4>
<p>so okay the conditions for <code>clone</code> removal could be given in terms of "miniRust", but certainly not in terms of any optimizations</p>



<a name="216024150"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024150" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024150">(Nov 08 2020 at 20:36)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations/near/216024094">said</a>:</p>
<blockquote>
<p>Right. And MIR isn't eligible as "miniRust" because it is still too big?</p>
</blockquote>
<p>well mostly it has a bunch of unnecessary stuff in it to accomodate a range of compiler passes</p>



<a name="216024156"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024156" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024156">(Nov 08 2020 at 20:36)</a>:</h4>
<p>adding another language to the pipeline seems like a major change, to say the least</p>



<a name="216024160"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024160" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024160">(Nov 08 2020 at 20:36)</a>:</h4>
<p>would miri work on miniRust instead of MIR?</p>



<a name="216024164"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024164" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024164">(Nov 08 2020 at 20:36)</a>:</h4>
<p>and it has some unnecsesary syntactic restrictions for places/values that do not help for a spec, they just help for implementation concerns</p>



<a name="216024170"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024170" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024170">(Nov 08 2020 at 20:37)</a>:</h4>
<p>oh I should clarify, I did not expect miniRust to be added to any pipeline</p>



<a name="216024173"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024173" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024173">(Nov 08 2020 at 20:37)</a>:</h4>
<p>it is a spec language</p>



<a name="216024175"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024175" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024175">(Nov 08 2020 at 20:37)</a>:</h4>
<p>though actually implementing it might be a fun exercise ;)</p>



<a name="216024176"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024176" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024176">(Nov 08 2020 at 20:37)</a>:</h4>
<p>yes, but if miri is to be a UB catcher it has to stay somewhat close to the spec</p>



<a name="216024189"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024189" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024189">(Nov 08 2020 at 20:37)</a>:</h4>
<p>sure</p>



<a name="216024234"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024234" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024234">(Nov 08 2020 at 20:38)</a>:</h4>
<p>as long as miniRust can be easily translated to MIR, that should be fine</p>



<a name="216024250"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024250" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024250">(Nov 08 2020 at 20:39)</a>:</h4>
<p>so conceivably we could have an alternate "spec compiler" that takes Rust -&gt; miniRust -&gt; MIR</p>



<a name="216024254"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024254" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024254">(Nov 08 2020 at 20:39)</a>:</h4>
<p>and hopefully is small and easily documentable</p>



<a name="216024256"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024256" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024256">(Nov 08 2020 at 20:39)</a>:</h4>
<p>a spec compiler would stop at miniRust I think</p>



<a name="216024263"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024263" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024263">(Nov 08 2020 at 20:39)</a>:</h4>
<p>MIR is an internal implementation detail of rustc</p>



<a name="216024309"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024309" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024309">(Nov 08 2020 at 20:40)</a>:</h4>
<p>ok so Rust -&gt; miniRust and then an interpreter on miniRust?</p>



<a name="216024333"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024333" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024333">(Nov 08 2020 at 20:41)</a>:</h4>
<p>miniRust is more like... if you look at the JS spec, they often specify surface-level operations as a sequence of small and precise steps. written in English. I am imagining something like that, except the steps are written in a programming language (with a formal spec in Coq if I can help it :D )</p>



<a name="216024407"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024407" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024407">(Nov 08 2020 at 20:42)</a>:</h4>
<p>that all sounds good, but it would be nice to have miniRust actually be executable (i.e. you have a computational interpretation in the Coq version, although that probably doesn't work as is because of termination. I don't know, stick some fuel argument in or something)</p>



<a name="216024415"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024415" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024415">(Nov 08 2020 at 20:43)</a>:</h4>
<p>sure, there are many things one could imagine longer-term</p>



<a name="216024417"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024417" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024417">(Nov 08 2020 at 20:43)</a>:</h4>
<p>but that's ways off at this point ;)</p>



<a name="216024469"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024469" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024469">(Nov 08 2020 at 20:44)</a>:</h4>
<p>I would think that a miniRust interpreter is not much different from a MIR interpreter in terms of difficulty, and we have the latter</p>



<a name="216024489"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024489" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024489">(Nov 08 2020 at 20:45)</a>:</h4>
<p>and miniRust -&gt; MIR would be an easy way to leverage miri for that purpose</p>



<a name="216024512"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216024512" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216024512">(Nov 08 2020 at 20:46)</a>:</h4>
<p>and then there would be the concrete (hopefully formally provable) correctness question of that miniRust -&gt; MIR map</p>



<a name="216027587"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216027587" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216027587">(Nov 08 2020 at 22:02)</a>:</h4>
<blockquote>
<p>I'd say that that C++ being able to remove copy constructors is more like Rust getting the ability to remove <code>Clone::clone</code> calls.  (Which seems plausible to me -- turning it into a move if it's known to be the last use after some MIR optimizations or what have you.)I'd say that that C++ being able to remove copy constructors is more like Rust getting the ability to remove <code>Clone::clone</code> calls.  (Which seems plausible to me -- turning it into a move if it's known to be the last use after some MIR optimizations or what have you.)</p>
</blockquote>
<p>That a separate thing I wanted, but it would require an RFC definitely. Ideally, x.clone() should be allowed to copy or move x if x is an lvalue and the program would not be ill-formed, and simply x if x is an rvalue (and thus elide the clone call in the case of it being an rvalue or something that can be copied/moved). This would be an elision, an explicitly permitted optimization that can alter observable behaviour.</p>
<blockquote>
<blockquote>
<p>Aren't the current plans for rust specification directed at the MIR? Or do you mean that this is an additional design constraint on the spec</p>
</blockquote>
<p>my plan was to do the spec in terms of some "miniRust" MIR-like language -- for languages with large surface syntax, it is usually best to first translate them to a "core language" and then give precise semantics to the core language</p>
</blockquote>
<p>Speaking as a compiler writer, I would rather it be in terms of rust. I don't want to be tied to a particular intermediate representation that I would diverge from anyways. Having it in terms of an intermediate representation would require either doing a multistage translation before even hitting the compilers actual IR (which is not what I would particularly like) or require working backwords to assign the meaning to the actual rust concepts and constructs (equally unappealing).<br>
I would also prefer it to be primarily or at least majorly written in prose, but I understand that may raise some issues. (I find it easier to both read and write prose specifications and standards).</p>



<a name="216031865"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216031865" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216031865">(Nov 08 2020 at 23:45)</a>:</h4>
<blockquote>
<p>I don't want to be tied to a particular intermediate representation that I would diverge from anyways.</p>
</blockquote>
<p>it's not an intermediate representation, it's a core calculus. that is something very different, at least conceptually.<br>
every single precise formal spec of a complex language that I know of uses this pattern of translating the huge amount of complexity in the surface language to a smaller core that can actually be understood, formalized, and explained. something where the syntax fits on half a page or less. usually that smaller core is not described as a language in its own right, but I do not think there is a good reason for that.<br>
this is not an IR that <em>any</em> compiler would use, but a crucial factoring step. we can either make our lives insanely difficult and try to work on a precise spec for full Rust directly, or we use established design techniques for how to split that unwieldy task into multiple manageable tasks. the former is like trying to build a compiler without an IR or any kind of abstraction barrier -- it's possible, but not a good idea.</p>



<a name="216031999"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216031999" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216031999">(Nov 08 2020 at 23:48)</a>:</h4>
<p>just like software engineering has developed techniques to make large software manageable through layers of abstraction, the same is true for language design. all I propose is that we build on top of decades of research on this subject instead of ignoring it.</p>



<a name="216032072"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216032072" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216032072">(Nov 08 2020 at 23:50)</a>:</h4>
<blockquote>
<p>I would also prefer it to be primarily or at least majorly written in prose, but I understand that may raise some issues. (I find it easier to both read and write prose specifications and standards).</p>
</blockquote>
<p>I'd be happy for someone to translate the formal spec to prose, but experience shows that making prose unambiguous and exhaustive is way harder than doing the same for math. so the normative spec should IMO be in a formal language, with prose explaining the less readable parts where necessary.<br>
the prose specs that I saw and actually liked (wasm, JS -- I only read snippets of either though) are basically just verbose notation for math, so that might be a reasonable middle ground. both of these are such that translating to math is straight-forward. (that's unlike e.g. C/C++ where translating even parts of the standard to math is something you can still write papers and even PhD theses about.)<br>
but anyway, any such spec is ways off currently, so it's not very helpful to discuss how exactly the spec should be presented.^^ either approach (prose/formal) can lead to a sufficiently precise spec, what is more important IMO is getting the overall structure right. and that's where I claim a core calculus is key. (wasm doesn't need one as it is tiny, and JS basically has one, they just do not call it a language.)</p>



<a name="216034096"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216034096" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216034096">(Nov 09 2020 at 00:40)</a>:</h4>
<blockquote>
<blockquote>
<p>I would also prefer it to be primarily or at least majorly written in prose, but I understand that may raise some issues. (I find it easier to both read and write prose specifications and standards).</p>
</blockquote>
<p>I'd be happy for someone to translate the formal spec to prose, but experience shows that making prose unambiguous and exhaustive is way harder than doing the same for math. so the normative spec should IMO be in a formal language, with prose explaining the less readable parts where necessary.</p>
</blockquote>
<p>Having both in the same document may actually be good. I happen to think the C++ standard is readable and reasonably understandable, but I can see your point, considering there are people who spend time trying to figure out what it actually says. The main reason I like prose is two-fold, it's easier to read and easier to cite (at least imo). I don't have to constantly refer to the base mathematical model in order to understand a particular section, and I have cited particular clauses of the C++ standard.</p>



<a name="216036628"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216036628" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Poliorcetics <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216036628">(Nov 09 2020 at 01:46)</a>:</h4>
<p>Having something verifiable through Coq (are there even other theorem provers used ?) sounds very nice but for people like me that have neither the time nor the skills to understand it all, having prose as a way to just read and cite some parts seems very important</p>



<a name="216055812"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216055812" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216055812">(Nov 09 2020 at 08:45)</a>:</h4>
<p>Actually my hope was that the precise version would look less like math and more like an idealized subset of safe Rust. :D It would be rather unconventional to use pseudo-Rust programs to specify the behavior of Rust (or miniRust), but I think it would actually work out very well and also help with the "formal math is very hard to read" problem.</p>



<a name="216055984"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216055984" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216055984">(Nov 09 2020 at 08:46)</a>:</h4>
<p>But to see if that really works, I should take some subset of miniRust and specify it that way; then we can gather feedback for how well people think this approach works. I just have no idea when I'll finally have the time to write up such things... there are always more discussions coming up elsewhere that prevent me form working on such lower priority tasks.^^</p>



<a name="216540358"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216540358" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216540358">(Nov 12 2020 at 22:44)</a>:</h4>
<p>Adding onto this, a couple of other reasonable optimizations I just came up, and I presume they are equally fine:</p>
<ul>
<li>copy-promotion, IE. promoting a copy to a move when the copied-from lvalue is a name, and that name is <em>definately-unused</em></li>
<li>In-place conversion, when a moved value is converted via a bitwise no-op, and the result is borrowed.</li>
</ul>
<p>One other question I had, could those be pseudo-applied to dereferenced pointers/lvalues? IE. if x is &amp;i8, could the compiler optimize &amp;(*x as u8) into a no-op, and just treat x as an &amp;u8? Or could that run into something with printing pointers?</p>



<a name="216549529"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216549529" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216549529">(Nov 13 2020 at 00:27)</a>:</h4>
<p>What does "promoting a copy to a move" mean when they are both effectively <code>memcpy</code>?</p>



<a name="216554234"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216554234" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216554234">(Nov 13 2020 at 01:28)</a>:</h4>
<p>In this case, it would allow the compiler to optimize based on the fact it's the last use, and in some cases, keep it in place.</p>



<a name="216642213"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216642213" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216642213">(Nov 13 2020 at 17:13)</a>:</h4>
<p>I expect LLVM already does that, but do you mean at the MIR level, perhaps?</p>



<a name="216663579"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216663579" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216663579">(Nov 13 2020 at 19:47)</a>:</h4>
<p>I am referring generally to any level of compilation employed by whatever compiler may be in use.</p>



<a name="216671883"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216671883" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216671883">(Nov 13 2020 at 20:56)</a>:</h4>
<p><span class="user-mention silent" data-user-id="138448">cuviper</span> <a href="#narrow/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations/near/216549529">said</a>:</p>
<blockquote>
<p>What does "promoting a copy to a move" mean when they are both effectively <code>memcpy</code>?</p>
</blockquote>
<p>MIR has different <code>Copy</code> and <code>Move</code> operands, so I can imagine turning a copy into a move would help other optimizations.</p>
<p>For example, doing that (<a href="https://github.com/rust-lang/rust/pull/46869">https://github.com/rust-lang/rust/pull/46869</a>) could allow a peephole <code>_2 = move _1; _3 = move _2</code> =&gt; <code>_3 = move _1</code> pass to be more effective (<a href="https://github.com/rust-lang/rust/pull/46440">https://github.com/rust-lang/rust/pull/46440</a>)</p>



<a name="216687796"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216687796" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216687796">(Nov 13 2020 at 23:24)</a>:</h4>
<p>OK, I didn't know MIR still distinguished that</p>



<a name="216697798"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216697798" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216697798">(Nov 14 2020 at 01:49)</a>:</h4>
<p>Looks like it still does: <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.Operand.html#variants">https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.Operand.html#variants</a></p>
<p>(There was a time when it didn't have it, though, IIRC.)</p>



<a name="216701921"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Copy%20Elision%20And%20related%20optimizations/near/216701921" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Copy.20Elision.20And.20related.20optimizations.html#216701921">(Nov 14 2020 at 03:13)</a>:</h4>
<p>I meant "still" as in the progression of lowering code, not the history of MIR. But I guess if IR is going to distinguish this at all, it would have to be after type resolution...</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>